package com.haredot.intercetor;

import com.haredot.annotation.DenyStudent;
import com.haredot.annotation.DenyTeacher;
import com.haredot.constraint.SysConst;
import com.haredot.entity.User;
import com.haredot.vo.R;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;

/**
 * 拦截并检查 权限
 */
public class SessionInterceptor extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        User currentUser = (User) request.getSession().getAttribute(SysConst.CURRENT_USER);
        // 判断是否登录，如果没有登录，则直接 跳转到登录页面，引导用户登录
        if (currentUser == null) {
            // 跳转到登录页面
            response.sendRedirect(request.getContextPath() + "/login");
            return false;
        }
        // 如果登录了， 获取控制器方法上是否有对应的 @Deny 权限注解
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            // 获取 对应的目标方法
            Method method = handlerMethod.getMethod();

            // 如果有该注解、则判断当前登录的是否是
            if (!method.isAnnotationPresent(DenyStudent.class) && !method.isAnnotationPresent(DenyTeacher.class)) return true;

            if ( (method.isAnnotationPresent(DenyStudent.class) && "student".equals(currentUser.getRole()))

                        || (method.isAnnotationPresent(DenyTeacher.class) && "teacher".equals(currentUser.getRole()))) {
                // 返回一个结果
                R<?> build = R.fail(R.StatusCode.FORBIDDEN).build();
                MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
                converter.write(build, MediaType.APPLICATION_JSON, new ServletServerHttpResponse(response));

                return false;
            }

            return true ;
        }
        return false;
    }
}
